package pathways;

/**
 * Title:        Pathways
 * Description:  Pure Java version of the Pathways Project.
 * Copyright:    Copyright (c) 2002
 * Company:      Ants Technologies
 * @author Veejay Sani
 * @version 1.0
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;

import pathways.Database.Implementation.CDBConnection;
import pathways.Database.Implementation.CDatabase;
import pathways.Database.Specialized.Visual.CDBSVSearchReaction;
import pathways.SpeciesSpace.IFinished;
import pathways.marvin_test.AtomTraceFrame;
import pathways.marvin_test.AtomTraceSearchFrame;
import pathways.util.Debug.CDebug;
import pathways.util.helper.CItem;

public class CMain extends JFrame{

  CPathway pathway;
  CPathwayPainter painter;
  JScrollPane jsp;
  CDatabase db;
  public static int RECTWIDTH = 100;
  public static int RECTHEIGHT = 50;

  class CFinishListener implements IFinished
  {
    private CSpanner span;

    public CFinishListener(CSpanner span)
    {
      this.span = span;
    }

    public void finished()
    {
      if (span.getSelectedPathway() != null)
         pathway.loadPathway(span.getSelectedPathway());
    }
  }

  public CMain(CPathway panel, CDatabase database)
  {
    db = database;
    pathway = panel;

    pathway.setOwner(this);

    panel.setPreferredSize(new Dimension(800,550));

    jsp = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

    jsp.setPreferredSize(new Dimension(800,550));

    jsp.getHorizontalScrollBar().setUnitIncrement(10);
    jsp.getVerticalScrollBar().setUnitIncrement(10);

    this.getContentPane().add(jsp, BorderLayout.CENTER);

    //this.setResizable(false);

    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

    JToolBar bar = new JToolBar();
    JButton btnNew = new JButton("New");
    JButton btnLoad = new JButton("Load");
    JButton btnSave = new JButton("Save");
    JButton btnAtomTracingView = new JButton("Atom-Tracing");
    JButton btnEditor = new JButton("Editor");
    JButton btnAtomTracing = new JButton("Enter Atom-Traces");
    JButton btnUpload = new JButton("Upload Mol File");
    JButton btnSpanner = new JButton("Spanner");

    bar.add(btnNew);
    bar.add(btnLoad);
    bar.add(btnSave);
    bar.add(btnAtomTracingView);
    bar.add(btnEditor);
    bar.add(btnAtomTracing);
    bar.add(btnUpload);
    bar.add(btnSpanner);

    btnNew.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnNew_actionPerformed(e);
      }
    });

    btnLoad.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnLoad_actionPerformed(e);
      }
    });

    btnSave.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnSave_actionPerformed(e);
      }
    });

    btnAtomTracingView.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnAtomTracingView_actionPerformed(e);
      }
    });

    btnEditor.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnEditor_actionPerformed(e);
      }
    });

    btnAtomTracing.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnAtomTracing_actionPerformed(e);
      }
    });

    btnUpload.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnUpload_actionPerformed(e);
      }
    });

    btnSpanner.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        btnSpanner_actionPerformed(e);
      }
    });

    this.getContentPane().add(bar,BorderLayout.NORTH);

    pack();
  }

  // event handlers for the toolbar
  void btnNew_actionPerformed(ActionEvent e)
  {
    pathway.disposeAndReCreate();

    askForFirstReactionInPathway(pathway,db);

    pathway.draw();
  }

  void btnLoad_actionPerformed(ActionEvent e)
  {
    //String strID = JOptionPane.showInputDialog(this,"Enter PathwayID:");
    //int id = Integer.parseInt(strID);

    CSearchPathway sp = new CSearchPathway(db,this);
    sp.show();

    CItem item = sp.getSelectedPathway();

    if (item == null) // user cancelled
       return;

    if (pathway.loadPathway(item.getID()))
    {
       JOptionPane.showMessageDialog(this,"Successfully Loaded");
       pathway.draw();
    }
    else
    {
      JOptionPane.showMessageDialog(this,"Unable to load");
    }
  }

  void btnSave_actionPerformed(ActionEvent e)
  {
    //JOptionPane.showMessageDialog(this,"Soon to come");

    String pathwayName = "";
    boolean found = false;

    // get a name to save by
    // if user cancels then return from func
    // if user does not enter anything then reprompt
    // if user enters a name that is already there then reprompt
    while (!found)
    {
      pathwayName = JOptionPane.showInputDialog(this,"Enter Pathway Name");

      found = true;

      if (pathwayName == null)
      {
        return; // user cancelled
      }

      if (pathwayName.equals(""))
      {
        JOptionPane.showMessageDialog(this,"Invalid entry");
        found = false;
      }

      if (db.getSelect().doesPathwayExist(pathwayName))
      {
        JOptionPane.showMessageDialog(this,"The Name " + pathwayName + " already exists.");
        found = false;
      }
    }

    // now that we have the name then lets try to save it
    try {
      db.getConnection().beginTrans();

      if (pathway.save(1,pathwayName)) //??? replace 1 with userID
      {
        db.getConnection().commitTrans();
        JOptionPane.showMessageDialog(this,"Saved Successfully.");
      }
      else
      {
        db.getConnection().rollbackTrans();
        JOptionPane.showMessageDialog(this,"Unable to save.");
      }
    } catch (SQLException sqle) {
      CDebug.println(this, "SQLException: " + sqle.toString());
    }
  }

  void btnAtomTracingView_actionPerformed(ActionEvent e)
  {
    JFrame mainFrame = new AtomTraceSearchFrame(pathway,db);
    mainFrame.setLocation(0, 0);
    mainFrame.pack();
    mainFrame.show();
  }

  void btnEditor_actionPerformed(ActionEvent e)
  {
    CEditReaction editRxn = new CEditReaction(null,db);

    editRxn.show();
    editRxn.requestFocus();
  }

  void btnAtomTracing_actionPerformed(ActionEvent e)
  {
    Rectangle dontcare = new Rectangle(0,0,100,100);

    CDBSVSearchReaction c = new CDBSVSearchReaction(db,this.getFrames()[0],dontcare,dontcare,0,2);
    c.show();

    CReaction rxn = c.getReaction();

    if (rxn != null)
    {
      rxn.read(rxn.getID(),db);

      JFrame mainFrame = new AtomTraceFrame(rxn,db);
      mainFrame.setLocation(0, 0);
      mainFrame.pack();
      mainFrame.show();
    }
  }

  void btnUpload_actionPerformed(ActionEvent e)
  {
    //JOptionPane.showMessageDialog(this,"Soon to come");

    CUploadFile uploadfile = new CUploadFile(db,this);

    uploadfile.doUpload();
  }

  void btnSpanner_actionPerformed(ActionEvent e)
  {
    CSpanner c = new CSpanner(db);
    /*
    Vector v = new Vector();
    Integer int1 = new Integer(1107);
    v.add(int1);
    int1 = new Integer(1987);
    v.add(int1);

    c.load(v);
    */
    CFinishListener listener = new CFinishListener(c);
    c.setFinishListener(listener);

    c.startSpanner();


  }

  public static void main(String args[])
  {
    setUpDebug();

    CDBConnection conn = new CDBConnection();

    try {
        conn.setClass("com.microsoft.jdbc.sqlserver.SQLServerDriver");
        conn.setConnect("jdbc:microsoft:sqlserver://127.0.0.1:1433;user=sa;password=sa;databasename=pathways;SelectMethod=cursor;");
    } catch (Exception excep)
    {
      //System.out.println("Unable to establish connection to database");
    }

    CDatabase db = new CDatabase(conn);
    CPathway p = null;

    initPathway(p,db);

    CMain main = new CMain(p,db);

    main.show();

    p.draw();
  }

  private static void initPathway(CPathway p, CDatabase db)
  {
    p = new CPathway(db);

    CSubstratePainter subPainter = new CSubstratePainter();
    CEnzymePainter enzymePainter = new CEnzymePainter();
    CPathwayPainter pathwayPainter = new CPathwayPainter(subPainter,enzymePainter);
    p.setPainter(pathwayPainter);

    CSubstrateMouseListener listener = new CSubstrateMouseListener(p);
    p.setSubstrateMouseListener(listener);
    CEnzymeMouseListener enzymeListener = new CEnzymeMouseListener(p);
    p.setEnzymeMouseListener(enzymeListener);

    askForFirstReactionInPathway(p,db);
  }

  private static void askForFirstReactionInPathway(CPathway p, CDatabase db)
  {
    Rectangle rect = new Rectangle(10,300,RECTWIDTH,RECTHEIGHT);
    Rectangle rect2 = new Rectangle(200,300,RECTWIDTH,RECTHEIGHT);

    CDBSVSearchReaction c = new CDBSVSearchReaction(db,new Frame(),rect,rect2,2,0);
    c.show();

    CReaction rxn = c.getReaction();

    if (rxn != null)
    {
      p.addReaction(rxn);
    }
  }

  private static void setUpDebug()
  {
    CDebug.addCategory("pathways.Database.Implementation.CDBConnection");
    CDebug.addCategory("pathways.Database.Specialized.Visual.CDBSVSearchBySubstrate");
    CDebug.addCategory("pathways.Database.Specialized.Visual.CProductListModel");
    CDebug.addCategory("pathways.Database.Specialized.Visual.CEnzymeListModel");
    CDebug.addCategory("pathways.CSubstrateMouseListener");
    CDebug.addCategory("pathways.CCompound");
    CDebug.addCategory("pathways.CReaction");
  }

  private void jbInit() throws Exception
  {
    this.addComponentListener(new java.awt.event.ComponentAdapter()
    {
      public void componentResized(ComponentEvent e)
      {
        this_componentResized(e);
      }
    });
  }

  void this_componentResized(ComponentEvent e)
  {
    System.out.println("resize called");
    jsp.setPreferredSize(this.getSize());
  }
}